package com.lcn.core.service.aop;

import com.lcn.comm.annotation.TxTransaction;
import com.lcn.comm.domain.TxRequest;
import com.lcn.comm.domain.TxTransactionInfo;
import com.lcn.comm.domain.TxTransactionLocal;
import com.lcn.comm.service.aop.AspectBeforeService;
import com.lcn.comm.service.aop.TransactionServerFactoryService;
import com.lcn.comm.service.aop.TransactionService;
import com.lcn.comm.util.RequestIdGenerator;
import com.weibo.api.motan.config.springsupport.BasicServiceConfigBean;
import com.weibo.api.motan.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * <p>切面服务实现</p>
 *
 * @author 张峰 zfvip_it@163.com
 * @create: 下午8:57
 */
@Service
public class AspectBeforeServiceImpl implements AspectBeforeService {

    @Resource
    private BasicServiceConfigBean basicServiceConfigBean;

    @Resource
    private TransactionServerFactoryService transactionServerFactoryService;


    /**
     * 切面处理
     *
     * @param groupId
     * @param point
     * @return
     * @throws Throwable
     */
    public Object around(String groupId, ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        TxTransaction txTransaction = method.getAnnotation(TxTransaction.class);
        TxTransactionLocal txTransactionLocal = TxTransactionLocal.current();
        TxRequest txRequest = getRequest(method, point.getArgs(), groupId);
        TxTransactionInfo txTransactionInfo = new TxTransactionInfo(txTransaction, txTransactionLocal, txRequest, groupId);
        TransactionService transactionService = transactionServerFactoryService.createTransactionService(txTransactionInfo);
        return transactionService.execute(point, txTransactionInfo);
    }

    /**
     * 获取请求对象
     *
     * @param method
     * @param args
     * @param groupId
     * @return
     */
    private TxRequest getRequest(Method method, Object[] args, String groupId) {
        TxRequest txRequest = new TxRequest();
        //事务组id
        txRequest.setGroupId(groupId);
        //请求id
        txRequest.setRequestId(RequestIdGenerator.getRequestId());
        //ip地址
        txRequest.setIpAddress(basicServiceConfigBean.getHost());
        //端口
        txRequest.setPort(getModulePort());
        //接口名称
        txRequest.setMethodName(method.getName());
        //参数类型描述
        txRequest.setParamtersDesc(ReflectUtil.getMethodParamDesc(method));
        //参数值
        txRequest.setArguments(args);
        return txRequest;
    }

    /**
     * 获取模块端口
     *
     * @return
     */
    private int getModulePort() {
        String export = basicServiceConfigBean.getExport();
        if (StringUtils.isNotBlank(export)) {
            return Integer.parseInt(export.split(":")[1]);
        }
        return 0;
    }
}
